﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Linq;
using System.Text;
using JetBrains.Annotations;
using YAFTS.Contracts;
using YAFTS.Utils;

namespace YAFTS.Core
{
	internal sealed class Configuration : IConfiguration
	{
		readonly ConcurrentDictionary<string, object> _locals = new ConcurrentDictionary<string, object>();

		private static T DefaultConverter<T>(string value)
		{
			return (T)TypeDescriptor.GetConverter(typeof(T)).ConvertFromString(value);
		}

		public T Get<T>(string key, Func<string, T> converter = null, T defaultValue = default(T))
		{
			if (key == null)
			{
				throw new ArgumentNullException("key");
			}

			object localValue;
			if(_locals.TryGetValue(key, out localValue) && localValue is T)
			{
				return (T) localValue;
			}

			return ConfigurationManager.AppSettings[key].With(converter ?? DefaultConverter<T>, defaultValue);
		}

		public int DefaultWordSize
		{
			get { return Get("DefaultWordSize", defaultValue: 30); }
			set { _locals["DefaultWordSize"] = value; }
		}

		public Encoding DefaultEncoding
		{
			get { return Get("DefaultEncoding", Encoding.GetEncoding, Encoding.Default); }
			set { _locals["DefaultEncoding"] = value; }
		}

		public string Filter
		{
			get { return Get("Filter", defaultValue: "*.txt"); }
			set { _locals["Filter"] = value; }
		}
	}
}
